/**
 *
 */
package cc.aileron.commons.util.function;

import java.util.Collection;
import java.util.List;

import cc.aileron.commons.util.SkipList;

/**
 * Collectionに対して高階関数的な操作を行なう為のメソッド郡
 * 
 * @author aileron
 */
public class CollectionFunctions
{
    /**
     * @param <P>
     * @param <R>
     * @param params
     * @return results
     */
    public static <P, R> CollectApply<P, R> collect(final Collection<P> params)
    {
        return new CollectApply<P, R>()
        {
            @Override
            public List<R> apply(final CollectFunction<P, R> function)
            {
                final SkipList<R> results = new SkipList<R>();
                for (final P p : params)
                {
                    final R r = function.each(p);
                    if (r != null)
                    {
                        results.add(r);
                    }
                }
                return results;
            }

        };
    }

    /**
     * @param <P>
     * @param params
     * @return results
     */
    public static <P> FillterApply<P> fillter(final Collection<P> params)
    {
        return new FillterApply<P>()
        {
            @Override
            public List<P> apply(final FillterFunction<P> function)
            {
                final SkipList<P> results = new SkipList<P>();
                for (final P p : params)
                {
                    if (!function.each(p))
                    {
                        continue;
                    }
                    results.add(p);
                }
                return results;
            }
        };
    }

    /**
     * @param <P>
     * @param <R>
     * @param params
     * @return results
     */
    public static <P, R> FlodApply<P, R> flod(final Collection<P> params)
    {
        return new FlodApply<P, R>()
        {
            @Override
            public R apply(final FlodFunction<P, R> function)
            {
                R ret = null;
                for (final P p : params)
                {
                    ret = function.each(ret, p);
                }
                return ret;
            }
        };
    }
}
